# -*- coding=utf-8 -*-
# Created Time: 2016年09月06日 星期二 11时16分34秒
# File Name: official.py

"""
正式环境
"""

from utils.routes      import route
from utils             import mongo
from utils.errors      import err_param
from utils.lib_time    import dt_str_now
from utils.pages       import pages_count
from utils.lib_re      import format_add_0, regex_char_trans

from service.base      import AuthHandler
from loog.mylog         import flogger as logger
from configure.config  import DB_NAME, COLL_CHANNEL, COLL_SEED,\
                              COLL_CHANNELPUB, COLL_CHANNELLOG
from asyncmongo.errors import IntegrityError

from service.index.record import keep

import json, tornado, pymongo


# 正式环境
@route(r'/official/channel/add', name='official_channel_add')
class OfficialChannelAddHandler(AuthHandler):
    """ 正式环境 - 添加渠道

    渠道ID: 字母+自增值
        每次取出最大的值+1，再格式化 C0001
        取最大值问题，asyncmongo 没有提供 $max 操作
        用 find limit 取最大的一个
    注意:
        1. 渠道名 - 不能重复
        2. 渠道识别码 - 前端需要判断识别码的格式
    """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        try:
            token    = self.request.headers.get('TData',{})
            udict    = json.loads(self.request.body)
            name     = udict['name']      # 渠道名
            ver      = udict['ver']       # 渠道识别码
            remark   = udict['remark']    # 备注
            created  = dt_str_now('str')  # 创建时间
            username = token['n']
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return

        # 生成类编号
        try:
            sort = [['clsno', pymongo.DESCENDING]]
            cls = yield tornado.gen.Task(
                            mongo.find_all,
                            DB_NAME,
                            COLL_CHANNEL,
                            {},
                            limit=1,
                            sort=sort)
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        if not cls:   # 创建第一条数据时
            no = format_add_0(1)
        else:
            no = format_add_0(int(cls[0]['clsno'][1:])+1)

        clsno = 'Q' + no
        keyword = name + ' ' + ver
        class_dict = {
            'name'   :name,
            'ver'    :ver,
            'clsno'  :clsno,
            'status' :1,
            'created':created,
            'remark' :remark,
            'keyword':keyword
        }

        note = {
            'created' :dt_str_now(),
            'type'    :'添加渠道',
            'obj'     :'正式渠道',
            'username':username,
            'keyword' :'正式渠道 添加渠道'
        }

        try:
            yield tornado.gen.Task(mongo.insert,DB_NAME,COLL_CHANNEL,class_dict)

            yield tornado.gen.Task(keep, note)
        except IntegrityError, e:
            logger.exception(e)
            self.write({'code':90001, 'data':e.msg})
            self.finish()
            return
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        self.write({'code':200})
        self.finish()


@route(r'/official/channel/detail', name='official_channel_detail')
class OfficialChannelDetailHandler(AuthHandler):
    """ 正式环境 - 渠道详情 """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        try:
            udict = json.loads(self.request.body)
            channel_id = udict['channel_id']
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return

        try:
            channel = yield tornado.gen.Task(
                            mongo.find_one,
                            DB_NAME,
                            COLL_CHANNEL,
                            {'_id':channel_id})
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        self.write({
            'code':200,
            'data':channel
        })
        self.finish()


@route(r'/official/channel/edit', name='official_channel_edit')
class OfficialChannelEditHandler(AuthHandler):
    """ 正式环境 - 编辑渠道 """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        try:
            token    = self.request.headers.get('TData',{})
            udict    = json.loads(self.request.body)
            channel_id = udict['channel_id']
            name     = udict['name']
            ver      = udict['ver']
            remark   = udict['remark']
            username = token['n']
            status   = int(udict.get('status', 1))
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return

        # 关键字修改问题
        keyword = name + ' ' + ver
        channel_dict = {
            'name'   :name,
            'remark' :remark,
            'ver'    :ver,
            'status' :status,
            'keyword':keyword
        }

        try:
            yield tornado.gen.Task(
                            mongo.update,
                            DB_NAME,
                            COLL_CHANNEL,
                            {'_id':channel_id},
                            channel_dict)
        except IntegrityError, e:
            logger.exception(e)
            self.write({'code':90001, 'data':e.msg})
            self.finish()
            return
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        if status == 0:
            note = {
                'created' :dt_str_now(),
                'type'    :'冻结渠道',
                'obj'     :'正式渠道',
                'username':username,
                'keyword' :'正式渠道 冻结渠道'
            }
            yield tornado.gen.Task(keep, note)

        self.write({'code':200})
        self.finish()


@route(r'/official/channel/list', name='official_channel_list')
class OfficialChannelListHandler(AuthHandler):
    """ 正式环境 - 渠道列表 """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            udict    = json.loads(self.request.body)
            keyword  = udict.get('keyword')
            page     = udict.get('page',1)
            limit    = udict.get('page_size', 15)
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return


        skip  = (page-1)*limit
        query = {}
        if keyword:
            keyword = regex_char_trans(keyword)
            query.update({'keyword': {'$regex':keyword}})

        logger.info(query)

        try:
            sort = [['created', pymongo.DESCENDING]]
            fields = {'keyword':0}
            seeds = yield tornado.gen.Task(
                                        mongo.find_all,
                                        DB_NAME,
                                        COLL_CHANNEL,
                                        query,
                                        skip=skip,
                                        limit=limit,
                                        sort=sort,
                                        fields=fields)
            count = yield tornado.gen.Task(
                                        mongo.count,
                                        DB_NAME,
                                        COLL_CHANNEL,
                                        sort,
                                        query)
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        pages = pages_count(count, limit)
        self.write({
            'code'     :200,
            'page'     :page,
            'page_size':limit,
            'pages'    :pages,
            'data'     :seeds
        })
        self.finish()


# 发布至此渠道
@route(r'/official/pub', name='official_pub')
class OfficialPubHandler(AuthHandler):
    """ 正式环境 - 发布

    Stuff:
        1. 渠道数据和包数据组成一个发布/数据
        2. 发布 用于包检查，包更新
        3. 记录发布操作记录
    """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):

        try:
            token      = self.request.headers.get('TData',{})
            udict      = json.loads(self.request.body)
            channel_id = udict['channel_id']   # 渠道id
            seed_id    = udict['seed_id']      # 测试包id
            content    = udict['content']      # 更新内容
            created    = dt_str_now('str')
            username   = token['n']
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return

        push_dict = {
            'channel_id' :channel_id,
            'seed_id'    :seed_id,
            'content'    :content,
            'created'    :created,
            'success'    :0,
            'fail'       :0,
            'devices'    :0,
            'pushed'     :1
        }

        try:
            # 获取渠道数据
            channel = yield tornado.gen.Task(
                            mongo.find_one,
                            DB_NAME,
                            COLL_CHANNEL,
                            {'_id':channel_id})
            if not channel: raise ValueError('channel_404')

            # 获取包数据
            seed = yield tornado.gen.Task(
                                mongo.find_one,
                                DB_NAME,
                                COLL_SEED,
                                {'_id':seed_id})
            if not seed: raise ValueError('seed_404')

            push_dict.update({
                'size'    :seed.get('bytes', 0),
                'low'     :seed.get('low', ''),
                'high'    :seed.get('high', ''),
                'version' :seed.get('version',''),
                'url'     :seed.get('url', ''),
                'md5'     :seed.get('md5', ''),
                'ts'      :seed.get('ts', 0),
                'info'    :seed.get('remark', ''),
                'max_str' :seed.get('max_str', ''),
                'finger'  :seed.get('finger', ''),

                'create_time' :seed.get('created', ''),
                'channel_name':channel.get('name', ''),
                'channel_ver' :channel.get('ver', ''),
                'keyword'     :channel.get('name','') + ' ' + channel.get('ver','')
            })

            log_dict = {
                'channel_id'  :channel_id,
                'channel_name':channel.get('name', ''),
                'channel_ver' :channel.get('ver', ''),
                'channel_no'  :channel.get('clsno', ''),
                'seed_id'     :seed_id,
                'content'     :content,
                'created'     :created,
                'username'    :username,
                'keyword'     :channel.get('name','') + ' ' + channel.get('clsno','')
            }

            yield tornado.gen.Task(
                                mongo.insert,
                                DB_NAME,
                                COLL_CHANNELPUB,
                                push_dict)

            yield tornado.gen.Task(
                                mongo.insert,
                                DB_NAME,
                                COLL_CHANNELLOG,
                                log_dict)
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        self.write({'code':200})
        self.finish()


@route(r'/official/pub/list', name='official_pub_list')
class ClassPushListHandler(AuthHandler):
    """ 正式环境 - 发布记录 - 列表 """

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            udict    = json.loads(self.request.body)

            keyword  = udict.get('keyword')
            page     = udict.get('page',1)
            limit    = udict.get('page_size', 30)
        except Exception, e:
            logger.exception(e)
            self.write(err_param)
            self.finish()
            return


        skip   = (page-1)*limit
        fields = {
            'success':1,
            'fail':1,
            'channel_name':1,
            'channel_ver' :1,
            'created':1
        }
        query  = {}
        if keyword:
            keyword = regex_char_trans(keyword)
            query.update({'keyword': {'$regex':keyword}})

        logger.info(query)
        try:
            sort = [['created', pymongo.DESCENDING]]
            seeds = yield tornado.gen.Task(
                                        mongo.find_all,
                                        DB_NAME,
                                        COLL_CHANNELPUB,
                                        query,
                                        fields=fields,
                                        skip=skip,
                                        limit=limit,
                                        sort=sort)
            count = yield tornado.gen.Task(
                                        mongo.count,
                                        DB_NAME,
                                        COLL_CHANNELPUB,
                                        sort,
                                        query)
        except Exception, e:
            logger.exception(e)
            self.write({'code':500})
            self.finish()
            return

        pages = pages_count(count, limit)
        self.write({
            'code'     :200,
            'page'     :page,
            'page_size':limit,
            'pages'    :pages,
            'data'     :seeds
        })
        self.finish()


